﻿using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 文章接口实现
    /// </summary>
    public class ArticleService : BaseService, IArticleService
    {
        public ArticleService(IDbContextFactory contentFactory) : base(contentFactory) { }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<Articles?> QueryAsync(Expression<Func<Articles, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<Articles>()
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ArticleCategory)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询文章前几条数据
        /// </summary>
        public async Task<IEnumerable<Articles>> QueryListAsync(int top, Expression<Func<Articles, bool>> funcWhere, string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            IQueryable<Articles> result = _context.Set<Articles>()
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ArticleCategory)
                .Where(funcWhere);
            result = result.OrderByBatch(orderBy);//调用Linq扩展类排序

            if (top > 0) result = result.Take(top);
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询文章分页数据
        /// </summary>
        public async Task<PaginationList<Articles>> QueryPageAsync(int pageSize, int pageIndex,
            Expression<Func<Articles, bool>> funcWhere, string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<Articles>()
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ArticleCategory)
                .Where(funcWhere);
            //调用Linq扩展类排序
            result = result.OrderByBatch(orderBy);
            return await PaginationList<Articles>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 获取记录总数量
        /// </summary>
        public async Task<int> QueryCountAsync(Expression<Func<Articles, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            return await _context.Set<Articles>().Where(funcWhere).CountAsync();
        }

        /// <summary>
        /// 更新数据(局部更新)
        /// </summary>
        public async Task<bool> UpdateAsync(Articles model, Expression<Func<Articles, int>> funcProperty, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var entry = _context.Entry<Articles>(model);
            //设置修改状态
            entry.State = EntityState.Unchanged;
            entry.Property(funcProperty).IsModified = true;
            //提交保存
            return await this.SaveAsync();
        }

        /// <summary>
        /// 更新浏览量(局部更新)
        /// </summary>
        public async Task<int> UpdateClickAsync(int articleId, int clickCount, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            Articles model = new();
            model.Id = articleId;
            model.Click = clickCount;
            var entry = _context.Entry<Articles>(model);
            //设置修改状态
            entry.State = EntityState.Unchanged;
            entry.Property(p => p.Click).IsModified = true;
            //提交保存
            bool result = await this.SaveAsync();
            return result ? model.Click : 0;
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<Articles, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //查找主表
            var artList = await _context.Set<Articles>().Where(funcWhere).ToListAsync();
            if (artList == null) return false;
            var artIds = artList.Select(x => x.Id).ToList();
            //查找关系表
            var reList = await _context.Set<ArticleCategoryRelation>().Where(x => artIds.Contains(x.ArticleId)).ToListAsync();
            //删除主从表
            _context.Set<ArticleCategoryRelation>().RemoveRange(reList);
            _context.Set<Articles>().RemoveRange(artList);
            //提交执行删除
            return await this.SaveAsync();
        }
    }
}
